package com.chart.web.controller.chart;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chart.chart.domian.ChartConfigsAndViewsVo;
import com.chart.chart.domian.ChartConfigsUser;
import com.chart.chart.domian.ChartFiles;
import com.chart.chart.domian.ChartViewsUser;
import com.chart.chart.service.IChartConfigsUserService;
import com.chart.chart.service.IChartFilesService;
import com.chart.chart.service.IChartViewsUserService;
import com.chart.common.annotation.Log;
import com.chart.common.core.controller.BaseController;
import com.chart.common.core.domain.AjaxResult;
import com.chart.common.enums.BusinessType;
import com.chart.common.utils.SecurityUtils;
import com.chart.common.utils.bean.BeanUtils;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.security.SecurityUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.bouncycastle.asn1.x500.style.RFC4519Style.l;

/**
 * 图表大屏
 *
 * @author chart
 */
@RestController
@RequestMapping("/file/chart")
public class ChartFilesController extends BaseController
{


    @Autowired
    private IChartFilesService chartFilesService;


    @Autowired
    private IChartConfigsUserService chartConfigsUserService;

    @Autowired
    private IChartViewsUserService chartViewsUserService;



    @ApiOperation("文件夹：列表")
    @GetMapping("/user/treeList")
    @Transactional
    public AjaxResult treeLsit(Long fileId)
    {
        //根据用户信息获取文件夹信息
        Long userId = SecurityUtils.getUserId();
        List<ChartFiles> list =chartFilesService.list(new LambdaQueryWrapper<ChartFiles>().eq(ChartFiles::getUserId,userId));

        for (int i = 0; i < list.size(); i++) {
            List<Long> ids = new ArrayList<>();
            ChartFiles chartFiles = list.get(i);
            ids.add(chartFiles.getFileId());
            //获取文件夹下大屏或者图表信息
            List<ChartConfigsAndViewsVo> configsAndViewsVoList = chartConfigsUserService.getChartsAndViewsBathByFileIds(ids);
            chartFiles.setChartConfigsAndViewsVos(configsAndViewsVoList);
        }


        //将数据转成树结构
        Map<Long, ChartFiles> map = list.stream().collect(Collectors.toMap(ChartFiles::getFileId, ChartFiles -> ChartFiles));
        ArrayList<ChartFiles> chartFiles = new ArrayList<>();
        map.forEach((key, value) -> {
                Optional.ofNullable(value.getParentId())
                        .map(map::get)
                        .ifPresent(pFile -> {
                            List<ChartFiles> children = pFile.getChildren();
                            if (children == null) {
                                pFile.setChildren(Stream.of(value).collect(Collectors.toList()));
                            } else {
                                children.add(value);
                            }
                        });
            if (!ObjectUtils.isEmpty(fileId)) {
                if (!ObjectUtils.isEmpty(value.getParentId())) {
                    if (value.getParentId().equals(fileId)) {
                        chartFiles.add(value);
                    }
                }
            }else {
                if (value.getParentId() == null) {
                    chartFiles.add(value);
                }
            }
        });
        return AjaxResult.success(chartFiles);
    }




    @ApiOperation("文件夹：新增")
    @PostMapping("/user/add")
    @Transactional
    public AjaxResult add(@RequestBody ChartFiles chartFiles)
    {
        if (ObjectUtils.isEmpty(chartFiles.getFileName())) {
            return AjaxResult.error("请填写文件夹名称");
        }
//        chartFiles.setParentId(chartFiles.getFileId());
//        chartFiles.setFileId(null);


        ChartFiles one;
        if (chartFiles.getParentId() == null) {
            one = chartFilesService.getOne(new LambdaQueryWrapper<ChartFiles>()
                    .isNull(ChartFiles::getParentId)
                    .eq(ChartFiles::getUserId, SecurityUtils.getUserId())
                    .eq(ChartFiles::getFileName, chartFiles.getFileName()));
        } else {
            one = chartFilesService.getOne(new LambdaQueryWrapper<ChartFiles>()
                    .eq(ChartFiles::getParentId, chartFiles.getParentId())
                    .eq(ChartFiles::getUserId, SecurityUtils.getUserId())
                    .eq(ChartFiles::getFileName, chartFiles.getFileName()));
        }
        if (!ObjectUtils.isEmpty(one)) {
            return AjaxResult.error("文件夹名称重复");
        }
        chartFiles.setUserId(SecurityUtils.getUserId());
        boolean result = chartFilesService.saveOrUpdate(chartFiles);
        if (result) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }


    @ApiOperation("文件夹：编辑")
    @PostMapping("/user/edit")
    @Transactional
    public AjaxResult edit(@RequestBody ChartFiles chartFiles)
    {
        if (ObjectUtils.isEmpty(chartFiles.getFileName())) {
            return AjaxResult.error("请填写文件夹名称");
        }

        ChartFiles one;
        if (chartFiles.getParentId() == null) {
            one = chartFilesService.getOne(new LambdaQueryWrapper<ChartFiles>()
                    .isNull(ChartFiles::getParentId)
                    .eq(ChartFiles::getUserId, SecurityUtils.getUserId())
                    .eq(ChartFiles::getFileName, chartFiles.getFileName()));
        } else {
            one = chartFilesService.getOne(new LambdaQueryWrapper<ChartFiles>()
                    .eq(ChartFiles::getParentId, chartFiles.getParentId())
                    .eq(ChartFiles::getUserId, SecurityUtils.getUserId())
                    .eq(ChartFiles::getFileName, chartFiles.getFileName()));
        }
        if (!ObjectUtils.isEmpty(one)) {
            return AjaxResult.error("文件夹名称重复");
        }

        boolean result = chartFilesService.saveOrUpdate(chartFiles);
        if (result) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    @ApiOperation("文件夹：图表/大屏移动")
    @PostMapping("/user/move")
    @Transactional
    public AjaxResult edit(@RequestBody ChartConfigsAndViewsVo chartConfigsAndViewsVo){
        if (chartConfigsAndViewsVo.getChartModeType()==1) {
            ChartConfigsUser one =null;
            //判断图表名称是否会重复
            if (ObjectUtils.isEmpty(chartConfigsAndViewsVo.getFileId())) {
                one = chartConfigsUserService.getOne(new LambdaQueryWrapper<ChartConfigsUser>().isNull(ChartConfigsUser::getFileId)
                        .eq(ChartConfigsUser::getUserId,SecurityUtils.getUserId()).eq(ChartConfigsUser::getChartName,chartConfigsAndViewsVo.getName()));
            }else {
                one = chartConfigsUserService.getOne(new LambdaQueryWrapper<ChartConfigsUser>().eq(ChartConfigsUser::getFileId, chartConfigsAndViewsVo.getFileId())
                        .eq(ChartConfigsUser::getUserId,SecurityUtils.getUserId()).eq(ChartConfigsUser::getChartName,chartConfigsAndViewsVo.getName()));
            }

            if (!ObjectUtils.isEmpty(one)) {
                return AjaxResult.error("图表名重复");
            }
            one=new ChartConfigsUser();
            one.setId(chartConfigsAndViewsVo.getId());
            one.setFileId(chartConfigsAndViewsVo.getFileId());
            boolean result = chartConfigsUserService.updateConfigTop(one);
            if (result) {
                return AjaxResult.success();
            }
        }else {
            ChartViewsUser one =null;
            if (ObjectUtils.isEmpty(chartConfigsAndViewsVo.getFileId())) {
                one = chartViewsUserService.getOne(new LambdaQueryWrapper<ChartViewsUser>().isNull(ChartViewsUser::getFileId)
                        .eq(ChartViewsUser::getUserId,SecurityUtils.getUserId()).eq(ChartViewsUser::getViewName,chartConfigsAndViewsVo.getName()));
            }else {
                one = chartViewsUserService.getOne(new LambdaQueryWrapper<ChartViewsUser>().eq(ChartViewsUser::getFileId, chartConfigsAndViewsVo.getFileId())
                        .eq(ChartViewsUser::getUserId,SecurityUtils.getUserId()).eq(ChartViewsUser::getViewName,chartConfigsAndViewsVo.getName()));
            }


            if (!ObjectUtils.isEmpty(one)) {
                return AjaxResult.error("图表名重复");
            }
            one=new ChartViewsUser();
            one.setId(chartConfigsAndViewsVo.getId());
            one.setFileId(chartConfigsAndViewsVo.getFileId());

            boolean result =chartViewsUserService.updateViewTop(one);

            if (result) {
                return AjaxResult.success();
            }
        }

        return AjaxResult.error();
    }


    @ApiOperation("文件夹：移动并创建副本")
    @PostMapping("/user/moveAndcopy")
    @Transactional
    public AjaxResult moveAndcopy(@RequestBody ChartConfigsAndViewsVo chartConfigsAndViewsVo)
    {
//        if (ObjectUtils.isEmpty(chartConfigsAndViewsVo.getCopyName())) {
//            return AjaxResult.error("请填写文件夹名称");
//        }
        chartConfigsAndViewsVo.setUserId(SecurityUtils.getUserId());
        List<ChartConfigsAndViewsVo> configsAndViewsVoList=chartConfigsUserService.getChartsAndViewsBatch(chartConfigsAndViewsVo);

        if (!ObjectUtils.isEmpty(configsAndViewsVoList)) {
            return AjaxResult.error("文件夹名称重复");
        }

        boolean result =false;
        if (chartConfigsAndViewsVo.getChartModeType()==1) {
            ChartConfigsUser configsUser = chartConfigsUserService.getById(chartConfigsAndViewsVo.getId());
            ChartConfigsUser chartConfigsUser = new ChartConfigsUser();
            BeanUtils.copyProperties(configsUser,chartConfigsUser);
            configsUser.setFileId(chartConfigsAndViewsVo.getFileId());
            chartConfigsUser.setId(null);

            List<ChartConfigsUser> list = new ArrayList<>();
            list.add(configsUser);
            list.add(chartConfigsUser);
            result = chartConfigsUserService.saveOrUpdateBatch(list);
        }else {
            ChartViewsUser viewsUser = chartViewsUserService.getById(chartConfigsAndViewsVo.getId());
            ChartViewsUser chartViewsUser = new ChartViewsUser();
            BeanUtils.copyProperties(viewsUser,chartViewsUser);
            viewsUser.setFileId(chartConfigsAndViewsVo.getFileId());
            chartViewsUser.setId(null);

            List<ChartViewsUser> list = new ArrayList<>();
            list.add(viewsUser);
            list.add(chartViewsUser);
            result = chartViewsUserService.saveOrUpdateBatch(list);
        }

        if (result) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }



    @ApiOperation("创建图表/大屏副本")
    @PostMapping("/user/copy")
    @Transactional
    public AjaxResult copy(@RequestBody ChartConfigsAndViewsVo chartConfigsAndViewsVo)
    {
        if(ObjectUtils.isEmpty(chartConfigsAndViewsVo.getCopyName()) || ObjectUtils.isEmpty(chartConfigsAndViewsVo.getId())) {
            return AjaxResult.error();
        }
        boolean b =false;
        if (chartConfigsAndViewsVo.getChartModeType()==1) {
            ChartConfigsUser chartConfigsUser=null;
            if (!ObjectUtils.isEmpty(chartConfigsAndViewsVo.getFileId())) {
                chartConfigsUser=chartConfigsUserService.getOne(new LambdaQueryWrapper<ChartConfigsUser>().eq(ChartConfigsUser::getFileId,chartConfigsAndViewsVo.getFileId()).
                        eq(ChartConfigsUser::getChartName,chartConfigsAndViewsVo.getCopyName()));
            }else {
                chartConfigsUser=chartConfigsUserService.getOne(new LambdaQueryWrapper<ChartConfigsUser>().isNull(ChartConfigsUser::getFileId)
                        .eq(ChartConfigsUser::getChartName,chartConfigsAndViewsVo.getCopyName()));
            }

            if (ObjectUtils.isEmpty(chartConfigsUser)) {
                ChartConfigsUser configsUser = chartConfigsUserService.getById(chartConfigsAndViewsVo.getId());
                configsUser.setChartName(chartConfigsAndViewsVo.getCopyName());
                configsUser.setId(null);
                configsUser.setFileId(chartConfigsAndViewsVo.getFileId());
                b = chartConfigsUserService.saveOrUpdate(configsUser);

                if (b) {
                    return AjaxResult.success(configsUser.getId());
                }
            }else {
                return AjaxResult.error("图表名称重复");
            }

        }else {
            ChartViewsUser chartViewsUser=  null;
            if (!ObjectUtils.isEmpty(chartConfigsAndViewsVo.getFileId())) {
                chartViewsUser=chartViewsUserService.getOne(new LambdaQueryWrapper<ChartViewsUser>().eq(ChartViewsUser::getFileId,chartConfigsAndViewsVo.getFileId()).
                        eq(ChartViewsUser::getViewName,chartConfigsAndViewsVo.getName()));
            }else {
                chartViewsUser=chartViewsUserService.getOne(new LambdaQueryWrapper<ChartViewsUser>().isNull(ChartViewsUser::getFileId)
                        .eq(ChartViewsUser::getViewName,chartConfigsAndViewsVo.getName()));
            }

            if (ObjectUtils.isEmpty(chartViewsUser)) {
                ChartViewsUser viewsUser = chartViewsUserService.getById(chartConfigsAndViewsVo.getId());
                viewsUser.setViewName(chartConfigsAndViewsVo.getCopyName());
                viewsUser.setId(null);
                viewsUser.setFileId(chartConfigsAndViewsVo.getFileId());
                b = chartViewsUserService.saveOrUpdate(viewsUser);

                if (b) {
                    return AjaxResult.success(viewsUser.getId());
                }
            }else {
                return AjaxResult.error("大屏名称重复");
            }
        }
        return AjaxResult.error();
    }

    @ApiOperation("文件夹：根据id获取文件夹详情")
    @GetMapping("/user/getInfo")
    public AjaxResult getInfo(ChartFiles chartFiles)
    {
        ChartFiles one = chartFilesService.getOne(new LambdaQueryWrapper<ChartFiles>().eq(ChartFiles::getFileId, chartFiles.getFileId()));
        return AjaxResult.success(one);
    }


    @ApiOperation("文件夹：根据id获取文件夹图表/大屏")
    @GetMapping("/user/getCharts")
    public AjaxResult getCharts(ChartConfigsUser chartConfigsUser)
    {
        chartConfigsUser.setUserId(SecurityUtils.getUserId());
        List<Long> ids = new ArrayList<>();
        ids.add(chartConfigsUser.getFileId());
        List<ChartConfigsAndViewsVo> list = chartConfigsUserService.getChartsAndViewsBathByFileIds(ids);
        return AjaxResult.success(list);
    }


    @ApiOperation("文件夹：根据id删除")
    @PostMapping("/user/del")
    @Transactional
    public AjaxResult del(@RequestBody ChartFiles chartFiles)
    {
        //获取到这个文件夹所有的下级目录和上一级目录
        List<Long> ids = getIds(chartFiles.getFileId());

        if (!CollectionUtils.isEmpty(ids)) {
            boolean a = chartFilesService.removeByIds(ids);
            if (a) {
                List<Long> fileids = new ArrayList<>();
                for (int i = 0; i < ids.size(); i++) {
                    Long aLong = ids.get(i);
                    List<ChartConfigsUser> list = chartConfigsUserService.list(new LambdaQueryWrapper<ChartConfigsUser>().eq(ChartConfigsUser::getFileId, aLong)
                            .eq(ChartConfigsUser::getUserId, SecurityUtils.getUserId()));
                    if (!CollectionUtils.isEmpty(list)) {
                        fileids.add(aLong);
                    }
                }


                if (!CollectionUtils.isEmpty(fileids)) {
                    List<ChartConfigsUser> configsUserList = chartConfigsUserService.list(new LambdaQueryWrapper<ChartConfigsUser>().in(ChartConfigsUser::getFileId, fileids));
                    if (!CollectionUtils.isEmpty(configsUserList)) {
                        boolean b = chartConfigsUserService.remove(new LambdaQueryWrapper<ChartConfigsUser>().in(ChartConfigsUser::getFileId,fileids));
                        if (b) {
                            List<ChartViewsUser> viewsUserList = chartViewsUserService.list(new LambdaQueryWrapper<ChartViewsUser>().in(ChartViewsUser::getFileId, fileids));
                            if (!CollectionUtils.isEmpty(viewsUserList)) {
                                boolean c = chartViewsUserService.remove(new LambdaQueryWrapper<ChartViewsUser>().in(ChartViewsUser::getFileId,fileids));
                                if (c) {
                                    return AjaxResult.success();
                                }
                            }else {
                                return AjaxResult.success();
                            }
                        }
                    }else {
                        List<ChartViewsUser> viewsUserList = chartViewsUserService.list(new LambdaQueryWrapper<ChartViewsUser>().in(ChartViewsUser::getFileId, fileids));
                        if (!CollectionUtils.isEmpty(viewsUserList)) {
                            boolean c = chartViewsUserService.remove(new LambdaQueryWrapper<ChartViewsUser>().in(ChartViewsUser::getFileId,fileids));
                            if (c) {
                                return AjaxResult.success();
                            }
                        }
                    }

                }else {
                    return AjaxResult.success();
                }

            }
        }
        return AjaxResult.error();
    }



    @ApiOperation("文件夹：打散文件")
    @PostMapping("/user/scatter")
    @Transactional
    public AjaxResult scatter(@RequestBody ChartFiles chartFiles)
    {
            List<Long> ids = getIds(chartFiles.getFileId());

            if (CollectionUtils.isEmpty(ids)) {
                return AjaxResult.error("不存在该文件夹");
            }
            //获取该用户下所有的文件夹和大屏
            List<ChartConfigsAndViewsVo> list = chartConfigsUserService.getChartsAndViewsBathByFileIds(ids);

            if (!CollectionUtils.isEmpty(list)) {

                boolean a=false;
                boolean b=false;

                //将信息进行分类
                Map<Integer, List<ChartConfigsAndViewsVo>> map = list.stream()
                        .collect(Collectors.groupingBy(ChartConfigsAndViewsVo::getChartModeType));
                //判断文件夹打散后，当前文件夹中文件是否重复
                if (!CollectionUtils.isEmpty(map.get(1))) {
                    List<ChartConfigsAndViewsVo> configUserList = map.get(1);
                    List<String> collect1 = configUserList.stream().map(ChartConfigsAndViewsVo::getName).collect(Collectors.toList());
                    List<ChartConfigsUser> oldList = chartConfigsUserService.list(new LambdaQueryWrapper<ChartConfigsUser>().in(ChartConfigsUser::getChartName, collect1).
                            eq(ChartConfigsUser::getUserId,SecurityUtils.getUserId()).isNull(ChartConfigsUser::getFileId));
                    if (!CollectionUtils.isEmpty(oldList)) {
                        List<String> collect2 = oldList.stream().map(ChartConfigsUser::getChartName).collect(Collectors.toList());
                        return AjaxResult.error(collect2+"文件夹内图表、大屏名称和外部重复");
                    }
                    List<ChartConfigsUser> collect = configUserList.stream().map(e -> {
                        ChartConfigsUser user = new ChartConfigsUser();
                        user.setId(e.getId());
                        user.setFileId(null);
                        return user;
                    }).collect(Collectors.toList());
                    a =chartConfigsUserService.scatterChartfigsUser(collect);
//                    a = chartConfigsUserService.saveOrUpdateBatch(collect);
                }
                if (!CollectionUtils.isEmpty(map.get(2))) {
                    List<ChartConfigsAndViewsVo> viewUserList = map.get(2);
                    List<String> collect1 = viewUserList.stream().map(ChartConfigsAndViewsVo::getName).collect(Collectors.toList());
                    List<ChartViewsUser> oldList = chartViewsUserService.list(new LambdaQueryWrapper<ChartViewsUser>().in(ChartViewsUser::getViewName, collect1).
                            eq(ChartViewsUser::getUserId,SecurityUtils.getUserId()).isNull(ChartViewsUser::getFileId));
                    if (!CollectionUtils.isEmpty(oldList)) {
                        List<String> collect2 = oldList.stream().map(ChartViewsUser::getViewName).collect(Collectors.toList());
                        return AjaxResult.error(collect2+"文件夹内图表、大屏名称和外部重复");
                    }
                    List<ChartViewsUser> collect = viewUserList.stream().map(e -> {
                        ChartViewsUser user = new ChartViewsUser();
                        user.setId(e.getId());
                        user.setFileId(null);
                        return user;
                    }).collect(Collectors.toList());
                    b =chartViewsUserService.scatterChartViewUser(collect);
//                    b = chartViewsUserService.saveOrUpdateBatch(collect);
                }
                if (!CollectionUtils.isEmpty(map.get(1))) {
                    if (!CollectionUtils.isEmpty(map.get(2))) {
                        if (b && a) {
                            return AjaxResult.success();
                        }
                    }else {
                        if (a) {
                            return AjaxResult.success();
                        }
                    }
                }else {
                    if (!CollectionUtils.isEmpty(map.get(2))) {
                        if (b ) {
                            return AjaxResult.success();
                        }
                    }
                }
            }else {
                return AjaxResult.success("该文件夹不存在图表、大屏");
            }
        return AjaxResult.error();
        }


    @ApiOperation("文件夹：根据名称筛选")
    @GetMapping("/user/list")
    @Transactional
    public AjaxResult getInfoByName(ChartConfigsAndViewsVo chartConfigsAndViewsVo)
    {
        chartConfigsAndViewsVo.setUserId(SecurityUtils.getUserId());

        List<ChartConfigsAndViewsVo> list = new ArrayList<>();

        //文件夹、图表、大屏的多表联合   进行根据名称进行筛选
        if (!ObjectUtils.isEmpty(chartConfigsAndViewsVo.getFileId())) {
            List<ChartConfigsAndViewsVo> fileList = chartConfigsUserService.getFiles(chartConfigsAndViewsVo);
            list.addAll(fileList);
                List<ChartConfigsAndViewsVo> cAvList = chartConfigsUserService.getChartsAndViewsBatch(chartConfigsAndViewsVo);
                list.addAll(cAvList);
        } else {
            list = chartConfigsUserService.getInfoByName(chartConfigsAndViewsVo);
            if (ObjectUtils.isEmpty(chartConfigsAndViewsVo.getName())) {
                list = list.stream().filter(e -> ObjectUtils.isEmpty(e.getParentId()) || ObjectUtils.isEmpty(e.getFileId())).collect(Collectors.toList());
            }
        }

        return AjaxResult.success(list);
    }



    //获取文件夹上下级的关联id
    private  List<Long> getIds(Long id){
        Long userId = SecurityUtils.getUserId();
        List<ChartFiles> list =chartFilesService.list(new LambdaQueryWrapper<ChartFiles>().eq(ChartFiles::getUserId,userId));
        Map<Long, ChartFiles> map = list.stream().collect(Collectors.toMap(ChartFiles::getFileId, ChartFiles -> ChartFiles));
        ArrayList<Long> ids = new ArrayList<>();
        map.forEach((key, value) -> {
            Optional.ofNullable(value.getParentId())
                    .map(map::get)
                    .ifPresent(pFile -> {
                        List<ChartFiles> children = pFile.getChildren();
                        if (children == null) {
                            pFile.setChildren(Stream.of(value).collect(Collectors.toList()));
                        } else {
                            children.add(value);
                        }
                    });
        });

        processChartFiles(map, id, ids);
        return ids;
    }

    private void processChartFiles(Map<Long, ChartFiles> map, Long id, List<Long> ids) {
        ChartFiles chartFiles1 = map.get(id);
        if (chartFiles1 == null) {
            return;
        }

        ids.add(chartFiles1.getFileId());

        if (chartFiles1.getChildren() != null) {
            chartFiles1.getChildren().forEach(child -> processChartFiles(map, child.getFileId(), ids));
        }
    }
}
